<?php
namespace Common\Util;

use Payment\Client\Charge;
use Payment\Client\Notify;
use Payment\Common\PayException;
use Payment\Client\Transfer;
use Payment\Config;
use Payment\Notify\PayNotifyInterface;

/**
 * 
 */
class Pay implements PayNotifyInterface
{
    public $config;
    public $errMsg = '';
    public $notify_type = '';
    
    /**
     * [run description]
     * @Author   张亚伟<1743325520@qq.com>
     * @DateTime 2018-07-10
     * @param    [type]                 $channel  支付类型
     * @param    [type]                 $metadata 支付数据
     * @return   [type]                           [description]
     */
    public function run($channel, $metadata)
    {
        $verify = $this->verify($channel, $metadata);
        try {
            $url = Charge::run($channel, $this->config, $metadata);
            return $url;
        } catch (PayException $e) {
            $this->errMsg = $e->errorMessage();
            return false;
        }
    }

    public function notify($type)
    {
        try {
            $this->notify_type = $type;
            $res = Notify::run($type, $this->config, $this);
            if($res == 'success'){
                return true;
            }
            $this->errMsg = $res;
            return false;
        } catch (PayException $e) {
            $this->errMsg = $e->errorMessage();
            return false;
        }
    }

    /**
     * 支付通知回调
     * @param    array                  $data [description]
     * @return   [type]                       [description]
     */
    public function notifyProcess(array $data)
    {
        trace($data, 'PAY_NOTIFY_PROCESS');
        switch ($this->notify_type) {
            case Config::ALI_CHARGE:
                if(!empty($data)){
                    if($data['trade_state'] == 'success'){
                        $res = update_pay_status($data['order_no']);
                        return $res['s'];
                    }
                }
                break;
            case Config::WX_CHARGE:
                return true;
                break;
            case Config::CMB_CHARGE:
                break;
            default:
                break;
        }
        return false;
    }

    public function errMsg()
    {
        return $this->errMsg;
    }

    public function verify($channel, $data)
    {
        $attributes = [];
        // 订单信息
        $orderNo = time() . rand(1000, 9999);
        switch ($channel) {
            case Config::ALI_CHANNEL_WAP:// 支付宝 手机网页 支付
                $attributes = [
                    'body'              => 'ali wap pay',
                    'subject'           => '测试支付宝手机网站支付',
                    'order_no'          => $orderNo,
                    'timeout_express'   => time() + 600,// 表示必须 600s 内付款
                    'amount'            => '0.01',// 单位为元 ,最小为0.01
                    'return_param'      => 'tata',// 一定不要传入汉字，只能是 字母 数字组合
                    'client_ip'         => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1',// 客户地址
                    'goods_type'        => '1',// 0—虚拟类商品，1—实物类商品
                    'store_id'          => '',
                    'quit_url'          => 'http://helei112g.github.io', // 收银台的返回按钮（用户打断支付操作时返回的地址,4.0.3版本新增）
                ];
                break;
            case Config::WX_CHANNEL_PUB:// 微信 公众账号 支付
                $attributes = [
                    'body'              => 'test body',// 商品描述
                    'subject'           => 'test subject',
                    'order_no'          => $orderNo,
                    'timeout_express'   => time() + 600,// 表示必须 600s 内付款
                    'amount'            => '3.01',// 微信沙箱模式，需要金额固定为3.01
                    'return_param'      => '123',
                    'client_ip'         => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1',// 客户地址
                    'openid'            => 'ottkCuO1PW1Dnh6PWFffNk-2MPbY',
                    'product_id'        => '123',
                ];
                break;
            case Config::WX_CHANNEL_WAP:// 微信wap支付，针对特定用户
                $attributes =  [
                    'body'              => 'test body',// 商品描述
                    'subject'           => 'test subject',
                    'order_no'          => $orderNo,
                    'timeout_express'   => time() + 600,// 表示必须 600s 内付款
                    'amount'            => '3.01',// 微信沙箱模式，需要金额固定为3.01
                    'return_param'      => '123',
                    'client_ip'         => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1',// 客户地址
                    //{"h5_info": {"type":"Wap","wap_url": "https://pay.qq.com","wap_name": "腾讯充值"}}
                    'scene_info'        => [
                        'type'      => 'Wap',// IOS  Android  Wap  腾讯建议 IOS  ANDROID 采用app支付
                        'wap_url'   => 'https://helei112g.github.io/',//自己的 wap 地址
                        'wap_name'  => '测试充值',
                    ],
                ];
                break;
            default:
                break;
        }
        return $data;
    }

    public function wechat($data = [])
    {
        $wechat = C('wechat');
        $this->config = [
            'use_sandbox'       => false,// 是否使用 微信支付仿真测试系统

            'app_id'            => $wechat['appid'],  // 公众账号ID
            'mch_id'            => $wechat['mch_id'],// 商户id
            'md5_key'           => $wechat['api_key'],// md5 秘钥
            'app_cert_pem'      => $wechat['sslcert_path'],//THINK_PATH.'../cert/apiclient_cert.pem',
            'app_key_pem'       => $wechat['sslkey_path'],//THINK_PATH.'../cert/apiclient_key.pem',
            'sign_type'         => 'MD5',// MD5  HMAC-SHA256
            'limit_pay'         => [
                //'no_credit',
            ],// 指定不能使用信用卡支付   不传入，则均可使用
            'fee_type'          => 'CNY',// 货币类型  当前仅支持该字段

            'notify_url'        => U('Pay/notify', [], true, true),

            // 'redirect_url'      => '',// 如果是h5支付，可以设置该值，返回到指定页面

            'return_raw'        => false,// 在处理回调时，是否直接返回原始数据，默认为true
        ];
        $this->config = array_merge($this->config, $data);
        return $this;
    }

    public function ali($data = [])
    {
        $this->config = [
            'use_sandbox'               => false,// 是否使用沙盒模式
            'app_id'                    => '2018032802462151',
            'seller_id'                 => '13524625822@139.com',
            'sign_type'                 => 'RSA',// RSA  RSA2
            // ！！！注意：如果是文件方式，文件中只保留字符串，不要留下 -----BEGIN PUBLIC KEY----- 这种标记
            // 可以填写文件路径，或者密钥字符串  当前字符串是 rsa2 的支付宝公钥(开放平台获取)
            'ali_public_key'            => THINK_PATH.'../cert/rsa_public_key_str.pem',
            // 可以填写文件路径，或者密钥字符串  我的沙箱模式，rsa与rsa2的私钥相同，为了方便测试
            'rsa_private_key'           => THINK_PATH.'../cert/rsa_private_key_str.pem',

            'limit_pay'                 => [
                //'balance',// 余额
                //'moneyFund',// 余额宝
                //'debitCardExpress',//     借记卡快捷
                //'creditCard',//信用卡
                //'creditCardExpress',// 信用卡快捷
                //'creditCardCartoon',//信用卡卡通
                //'credit_group',// 信用支付类型（包含信用卡卡通、信用卡快捷、花呗、花呗分期）
            ],// 用户不可用指定渠道支付当有多个渠道时用“,”分隔
            // 与业务相关参数
            'notify_url'                => U('Pay/ali_notify', [], true, true),
            'return_url'                => '',
            'return_raw'                => false,// 在处理回调时，是否直接返回原始数据，默认为 true
        ];
        $this->config = array_merge($this->config, $data);
        return $this;
    }
}